﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using MySql.Data.MySqlClient;
using iRealtor.Maps.DataAccess.Models;

namespace iRealtor.Maps.DataAccess.Dao.EntityDataProviders
{
	public abstract class EntityDataProvider<TEntity> where TEntity : Entity
	{
		public abstract void Save(TEntity entity, IMySqlCommandCreater cmdCreater);
		public abstract TEntity Load(object key, IMySqlCommandCreater cmdCreater);
		public abstract TEntity Load(DataRow row);

		public IList<TEntity> Load(MySqlCommand selectCommand)
		{
			MySqlDataAdapter adapt = new MySqlDataAdapter(selectCommand);
			DataTable dt = new DataTable();
			adapt.Fill(dt);

			return (from row in dt.Rows.Cast<DataRow>()
					select Load(row)).ToList();
		}

		public static EntityDataProvider<TEntity> CreateProvider()
		{
			if (!providers.ContainsKey(typeof(TEntity)))
			{
				throw new Exception(string.Format("Can not find EntityDataProvider for {0}", typeof(TEntity).Name));
			}
			return (EntityDataProvider<TEntity>)providers[typeof(TEntity)];
		}

		public void Register()
		{
			if (providers.ContainsKey(typeof(TEntity)))
			{
				throw new Exception(string.Format("EntityDataProvider for {0} already registered", typeof(TEntity).Name));
			}
			providers.Add(typeof(TEntity), this);
		}

		public void UnRegister()
		{
			if (!providers.ContainsKey(typeof(TEntity)))
			{
				throw new Exception(string.Format("EntityDataProvider for {0} is not registered", typeof(TEntity).Name));
			}
			else if (providers[typeof(TEntity)].GetType() != this.GetType())
			{
				throw new Exception(string.Format("EntityDataProvider {0} is not registered for {0}", typeof(TEntity).Name));
			}

			providers.Remove(typeof(TEntity));
		}

		private static IDictionary<Type, object> providers = new Dictionary<Type, object>(){
			{typeof(Place), new PlacesDataProvider()},
			{typeof(PlaceImage), new PlaceImagesDataProvider()},
			{typeof(Group), new GroupsDataProvider()}
		};
	}
}
